package com.freecloud.javabasics.design.delegate.servlet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 委派模式
 * @Author: maomao
 * @Date: 2019-11-18 09:37
 */
public class ServletDispatcher {

    private List<Handler> handlerList = new ArrayList<>();

    public ServletDispatcher(){
        Class<?> menber = MemberController.class;
        try {
            Handler systemHander = new Handler();
            systemHander.setController(menber.newInstance());
            systemHander.setMethod(menber.getMethod("getMenuById",new Class[]{String.class}) );
            systemHander.setUrl("/web/getMenuById.json");

            handlerList.add(systemHander);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public void doService(HttpServletRequest request, HttpServletResponse response){
        doDispatch( request,  response);
    }

    private void doDispatch(HttpServletRequest request, HttpServletResponse response){

        //1. 获取用户请求的URL（护宝娇娃 J2EE的标准，一个URL对应一个servlet）
        String url = request.getRequestURI();

        //2. servlet拿到URL，要做权衡（判断、选择）（根据用户请求的URL）

        //3. 通过url去handlerMapping拿到策略常亮
        Handler handler = null;
        for(Handler h: handlerList){
            if(h.getUrl().equals(url)){
                handler = h;
                break;
            }
        }

        //4. 将具体任务分发到method（通过反射去调用）
        Object result = null;
        try {
            result = handler.getMethod().invoke(handler.controller,request.getParameter("id"));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        //5. 获取到method执行结果，通过response返回
        try {
            response.getWriter().write(String.valueOf(result));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    class Handler{
        private Object controller;
        private Method method;
        private String url;

        public Object getController() {
            return controller;
        }

        public void setController(Object controller) {
            this.controller = controller;
        }

        public Method getMethod() {
            return method;
        }

        public void setMethod(Method method) {
            this.method = method;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }
    }
}
